<template>
    <div class="Chat">
      <el-scrollbar height="800px" ref="scrollMenuRes">
        <div v-for="(item,index) in msgList" :key="index">
          <!-- 用户 -->
          <div class="user-box">
            <el-row>
              <el-col :span="12"></el-col>
              <el-col class="content" :span="8">
                <div>{{ item.user }}</div>
              </el-col>
              <el-col :span="2">
                <el-avatar :size="50" src="https://cube.elemecdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png" />
              </el-col>
            </el-row>
          </div>

          <!-- AI 回答 -->
          <div class="ai-box">
            <el-row>
              <el-col :span="2">
                <el-avatar :size="50" src="https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png" />
              </el-col>
              <el-col class="content" :span="8">
                <!-- <div v-if="chunksTxt" class="time" v-html="chunksTxt"></div> -->
                <div id="output">{{ item.bot }}</div>
                <!-- <div id="output">{{ content }}</div> -->
              </el-col>
              <el-col :span="12"></el-col>
            </el-row>
          </div>

        </div>
      </el-scrollbar>

      <el-footer>
        <!-- <el-input type="textarea"></el-input> -->
        <el-input
          class="question-input"
          v-model="msgValue"
          style="max-width: 1000px"
          placeholder="请输入..."
          @keyup.enter="initStream"
          :disabled="inputDisabled"
        >
          <template #prepend><el-icon><FolderOpened /></el-icon></template>
          <template #append>
            <el-button @click="initStream"><el-icon><Promotion /></el-icon></el-button>
          </template>
        </el-input>
      </el-footer>
    </div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { Promotion,FolderOpened } from '@element-plus/icons-vue';
import axios from 'axios';
// import { Readable } from 'stream';
import data from '../utils/data.json'
import { fetchEventSource } from '@microsoft/fetch-event-source';
import { useRouter,useRoute } from 'vue-router';
let router = useRouter();
let route = useRoute();
let msgValue = ref('')
let chunksTxt = ref('')
let session_id = ref(12)
let msgList = ref([
  {
    "bot": "当然可以！不过您需要提供一下文章的内容或者主题，这样我才能根据具体内容给出一个准确、有用的评价。如果您能分享文章的主要内容、观点或题材，我会更好地为您服务！",
    "user": "对这篇文章写个评价",
  },
  {
    "bot": "雨夜，林深雾浓。年轻画家陆川撑着伞，走在荒废的山路上。他要去拜访一位隐居的老画家，传说那里的画作能预示未来。\n\n忽然，一阵冷风吹过，前方出现一个模糊的身影。是个女孩，浑身湿透，眼神空洞。“先生……请帮我找回家。”她的声音微弱却刺骨。陆川犹豫片刻，决定带她同行。\n\n到达破旧的木屋时，天已全黑。点燃蜡烛后，陆川发现女孩竟消失无踪，只留下一幅未完成的油画——画中的景象正是他刚才走过的路，而角落里多了一个撑伞的人影。\n\n深夜翻阅老画家留下的笔记，陆川才知这里几十年前溺亡过一名少女，而她的模样，与今晚遇见的女孩一模一样。",
    "user": "写200字的小说",
  },
  {
    "bot": "当然可以！不过您需要提供一下文章的内容或者主题，这样我才能根据具体内容给出一个准确、有用的评价。如果您能分享文章的主要内容、观点或题材，我会更好地为您服务！",
    "user": "对这篇文章写个评价",
  },
  {
    "bot": "雨夜，林深雾浓。年轻画家陆川撑着伞，走在荒废的山路上。他要去拜访一位隐居的老画家，传说那里的画作能预示未来。\n\n忽然，一阵冷风吹过，前方出现一个模糊的身影。是个女孩，浑身湿透，眼神空洞。“先生……请帮我找回家。”她的声音微弱却刺骨。陆川犹豫片刻，决定带她同行。\n\n到达破旧的木屋时，天已全黑。点燃蜡烛后，陆川发现女孩竟消失无踪，只留下一幅未完成的油画——画中的景象正是他刚才走过的路，而角落里多了一个撑伞的人影。\n\n深夜翻阅老画家留下的笔记，陆川才知这里几十年前溺亡过一名少女，而她的模样，与今晚遇见的女孩一模一样。",
    "user": "写200字的小说",
  }
])
const content = ref('') // 界面向用户逐字输出的内容
const stringB = ref("") // 接口返回的完整内容

let inputDisabled = ref(false)

const streamText = ref('');
let eventSource = null;
let scrollMenuRes = ref(null);
// 初始化 EventSource 连接
const initStream = () => {
  let params = {
    session_id : session_id.value,        
    text : msgValue.value    
  }
  let new_msg  = {
    "bot": '思考中...',
    "user": msgValue.value,
    "chunks":""
  }
  let num = 0
  msgList.value.push(new_msg)

  const formData = new FormData()
  formData.set('session_id', session_id.value)
  formData.set('text', msgValue.value)
  inputDisabled.value = true
  const ctrlAbout = new AbortController();
  // 取回答
  eventSource = fetchEventSource('http://106.15.186.55:6008/api/v1/chat_bot/chatbot', {
    method: 'POST',
    headers: {
      'GVAPY-API-KEY': 'cf85a6770e16639f2388ea68c7d85d09',
      // 'Accept': "text/event-stream",
      // 这里不用设置 Content-Type，当你使用 FormData 时，fetch 会自动设置
      // "Content-type": "multipart/form-data;",
    },
    // body: JSON.stringify(params), // json用body
    body: formData, // form-data用data
    signal: ctrlAbout.signal,
    onmessage(event) {
      let chunksArr = JSON.parse(event.data).reference_graph.chunks
      chunksTxt.value = ''
      // console.log(JSON.parse(event.data).reference_graph);
      if(num == 0){
        msgList.value[msgList.value.length - 1].bot = ''
        chunksArr.map(item=>{
          chunksTxt.value += item
        })
        msgList.value[msgList.value.length - 1].chunks = chunksTxt
        console.log(chunksTxt.value);
        // console.log(msgList.value[msgList.value.length - 1].chunks);
      }

      // 显示格式文本
      // if(JSON.parse(event.data).chunks){
      //   msgList.value[msgList.value.length - 1].chunks = JSON.parse(event.data).chunks
      // }
      if(JSON.parse(event.data).content){
        msgList.value[msgList.value.length - 1].bot += JSON.parse(event.data).content
        num += 1
      }
      content.value += JSON.parse(event.data).content
      inputDisabled.value = false
      msgValue.value = ''
      scrollToBottom()

    },
    onerror() {
      console.log('err')
      inputDisabled.value = false
    }
  })
};

// 创建一个用于连接 SSE 的函数
function connectSSE() {
  const formData = new FormData()
  formData.set('session_id', session_id.value)
  formData.set('text', msgValue.value)

  const sseSource = axios.post(
    '/api/v1/chat_bot/chatbot',
    formData,
    {
      responseType: 'stream',
        headers: {
          'GVAPY-API-KEY': 'cf85a6770e16639f2388ea68c7d85d09',
          'Data-Type': 'text/event-stream',
          'Content-Type': 'multipart/form-data',
        },
    }
  );

  // 处理响应流
  // sseSource.then(response => {
  //   const reader = response.data.getReader();
  //   readStream(reader);
  // })
  // .catch(error => {
  //   console.error('Error connecting to SSE:', error);
  // });

  sseSource.then(response => response.body)
      .then(res => res.on('readable', () => {
      let chunk;
      while (null !== (chunk = res.read())) {
        console.log(chunk.toString());
      }
  }))
}

const userQuestion = (question) => {
  let msgValue = {
    text: question,
    msgFrom: 0,
    userId: 1
  };
  msgList.value.push(msgValue);
};
const AIReplay = (replay) => {
  let autoReplyMsg = {
    text: replay,
    msgFrom: 1,
    userId: 1
  };
  msgList.value.push(autoReplyMsg);
};
// AI中的逐字输出
function print () {
  // 如果向用户输出内容已经全部完成，则退出逐字输出
  if (content.value.length >= stringB.value.length) {
    // 退出递归
    inputDisabled.value = false
    return;
  } else {
    // content仍然比stringB短，进入下一次等待和递归
    setTimeout(() => {
      content.value += stringB.value.charAt(content.value.length);
      inputDisabled.value = true
      print(content, stringB);
    }, 50);
  }
}

function getHistory() {
  axios.get('http://106.15.186.55:6008/api/v1/chat_bot/histories/{session_id}?id=' + session_id.value, {
      headers: {
        'GVAPY-API-KEY': 'cf85a6770e16639f2388ea68c7d85d09',
      },
    }
  ).then(res => {
    if(JSON.stringify(res.data.data) == "{}"){
      msgList.value = []
    }else{
      msgList.value = res.data.data.history.message
    }
    if(route.query.key){
      msgValue.value = route.query.key
      // initStream()
    }
    scrollToBottom()
    console.log(msgList.value)
  })
}
//滚动面板自动滑动到底部
const scrollToBottom = () => {
  if (scrollMenuRes.value) {
    const container = scrollMenuRes.value.$el.querySelector('.el-scrollbar__wrap');
    // console.log(scrollMenuRes.value.$el.querySelector('.el-scrollbar__view').height)
    container.style.scrollBehavior = 'smooth'; // 添加平滑滚动效果
    container.scrollTop = container.scrollHeight;
  }
}
// 读取流式数据
async function readStream(reader) {
  const decoder = new TextDecoder('utf-8');
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    // 解码数据并处理
    const message = decoder.decode(value);
    console.log('Received:', message);
  }
}

onMounted(() => {
  if(route.query.id){ // 通过路由参数获取session_id
    session_id.value = route.query.id || 10
  }
  // Vue3中没有this，访问全局变量比较麻烦，手动获取this并挂载到window，页面中可以直接使用window.$this获取Vue实例
  getHistory()

})
</script>
<style lang="scss">
.Chat{
  position: relative;
  .el-footer{
    position: fixed;
    bottom: 0;
    width: 87%;
    height: 160px;
    border-top: 1px solid #ccc;
    padding: 10px;
    box-sizing: border-box;
    background: #fff;
    .question-input{
      margin: 40px 0;
      height: 40px;
    }
  }
  .content{
    text-align: left;
    border-radius: 8px;
    background-color: #f5f7fa;
    padding: 10px;
    height: auto;
  }
  .user-box{
    margin-bottom: 50px;
  }
  .ai-box{
    margin-bottom: 50px;
  }
}
</style>